import Taro from '@tarojs/taro'
import { useEffect, useState } from 'react'

const toast_img = ''

declare namespace wx {
  abstract class env {
    /** 文件系统中的用户目录路径 (本地路径) */
    static USER_DATA_PATH: string;
  }
}
export const USER_DATA_PATH = wx.env.USER_DATA_PATH;
export const fs = Taro.getFileSystemManager();

type TIcon = "success" | "loading" | "none" | undefined
interface IToastOpt {
  image?: string | undefined;
  icon?: TIcon;
  duration?: number
  complete?: Function
}

export const showToast = (title, { image = undefined, icon = 'none', duration = 2000, complete = void {} }: IToastOpt = {}) => {
  return Taro.showToast({
    title,
    icon,
    image,
    duration,
    complete: () => {
      setTimeout(() => {
        complete && complete()
      }, duration)
    }
  })
}

interface IArgs {
  key: string;
  value: any
}
// 表单校验函数
interface IRules {
  [propName: string]: {
    rule: {
      required?: boolean
      re?: Function | RegExp
    },
    msg: {
      required?: string;
      re?: string;
    }
  }
}
export const validator = (args: IArgs[], rules: IRules, hasToastImage: boolean = true) => {
  for (let i = 0; i < args.length; i++) {
    const {key, value} = args[i]
    const { rule, msg } = rules[key]
    // 是否是必填项
    if (rule.required && !value) {
      showToast(msg.required, { image: hasToastImage ? toast_img : undefined })
      return false
    }

    // 是否有校验规则
    if (rule.re && value) {
      if ((typeof rule.re === 'function' && !rule.re(value)) || (typeof rule.re === 'object' && rule.re instanceof RegExp && !rule.re.test(value))) {
        showToast(msg.re, { image: hasToastImage ? toast_img : undefined })
        return false
      }
    }
  }
  return true
}

// 倒计时Hook
export const useInterval = (timer) => {
  const [num, setNum] = useState(timer)
  const [startInterval, setStartInterval] = useState(false)

  useEffect(() => {
    if (startInterval) {
      setTimeout(() => {
        if (num -1 > 0) {
          setNum(num - 1)
        } else {
          setStartInterval(false)
          setNum(timer)
        }
      }, 1000)
    }
  }, [num, startInterval, timer])

  return [num, setStartInterval]
}

// 打印日志
export const log = (...args) => {
  console.warn(...args)
}

export function base64ToUrl(base64Data) {
  var base64 = base64Data.replace(/[\r\n]/g, ''); //res.data是后端返给你的base64，有时候会存在换行符，
  // 小程序端解析不了，你需要自己做处理
  // var array = Taro.base64ToArrayBuffer(base64)
  const FILE_BASE_NAME = new Date().getTime();
  const filePath = USER_DATA_PATH + '/' + FILE_BASE_NAME + '.png';

  return new Promise<string>((resolve) => {
    fs.writeFile({
      filePath,
      data: base64,
      encoding: 'base64',
      success() {
        resolve(filePath);
      },
      fail(err) {
        Taro.showToast({
          title: '图片解码失败',
          icon: 'none',
        });
        // 临时存储满了需要清除存储
        removeFileList()
      },
    });
  });
}
// 删除本地文件
export function removeFileList() {
  try {
    const tmpFileList = fs.readdirSync(USER_DATA_PATH)

    for(var i = 0; i < tmpFileList.length; i++) {
      if (/(.png)|(.gif)|(.jpeg)|(.jpg)$/.test(tmpFileList[i])) {
        fs.unlinkSync(USER_DATA_PATH + '/' + tmpFileList[i])
      }
    }

    const fileList = fs.readdirSync(USER_DATA_PATH)
    console.log('清除后的tmpFileList', fileList)
  } catch(e){}
}
export function toDouble (num) {
  return num >= 0 && num <= 9 ? `0${num}` : `${num}`
}
// 将秒转换成 00:00格式
export function secondFormat(s) {
  if (s < 60) {
    return `00:${toDouble(parseInt(`${s}`, 10))}`
  } else {
    const tenPos = parseInt(`${s/60}`, 10)
    const onePos = parseInt(`${s%60}`, 10)
    return `${toDouble(tenPos)}:${toDouble(onePos)}`
  }
}
// 音频hook
export function useAudioContext (setPlayingIndex) {
  const [innerAudioContext] = useState(Taro.createInnerAudioContext())

  useEffect(() => {
    Taro.setInnerAudioOption({
      mixWithOther: false,
      obeyMuteSwitch: false,
      success: res => { console.log('***', res)}
    })
    return () => innerAudioContext.destroy()
  }, [innerAudioContext])

  useEffect(() => {
    innerAudioContext.onPlay(() => {
    })
    innerAudioContext.onPause(() => {
    })
    innerAudioContext.onStop(() => {
    })
    innerAudioContext.onEnded(() => {
      setPlayingIndex('')
    })
    innerAudioContext.onTimeUpdate(() => {
    })
  }, [innerAudioContext, setPlayingIndex])

  return [innerAudioContext]
}

export function formatTime(timestamp, rule='YYYY-MM-DD hh:mm:ss') {
  const _timestamp = +timestamp
  if (!_timestamp) return ''
  const d = new Date(_timestamp)
  const year = d.getFullYear(),
        month = toDouble((d.getMonth() + 1)),
        day = toDouble(d.getDate()),
        hour = toDouble(d.getHours()),
        minute = toDouble(d.getMinutes()),
        second = toDouble(d.getSeconds())

  return rule.replace(/YYYY/, year.toString())
      .replace(/MM/, month)
      .replace(/DD/, day)
      .replace(/hh/, hour)
      .replace(/mm/, minute)
      .replace(/ss/, second)
}

export function getRole(dutyId) {
  return {
    isPartTimeTeacher: +dutyId === 3 || +dutyId === 4,
    isFullTimeTeacher: +dutyId === 1 || +dutyId === 2 || +dutyId === 3,
    isSystemTeacher: +dutyId === 2 || +dutyId === 4,
  }
}

  // 通过生日时间戳计算多少岁、几个月
export function getAgeByBrithday(birth) {
  if (!+birth) return ''
  var age = 0
  var month = 0
  var today = new Date()
  var todayYear = today.getFullYear()
  var todayMonth = today.getMonth() + 1

  const birthday = new Date(Number(birth) * 1000)
  const birthdayYear = birthday.getFullYear()
  const birthdayMonth = birthday.getMonth() + 1

  if (today.getTime() < birthday.getTime()) {
    console.log('无法计算')
  } else {
    age = todayYear - birthdayYear

    if (todayMonth <= birthdayMonth) {
      month = todayMonth - birthdayMonth + 12
      age--
    } else {
      month = todayMonth - birthdayMonth
    }
    return age + '岁' + month + '个月'
  }
}

// 更新小程序 isForce 强制升级
export const updateWeapp = (isForce?: boolean): void => {
  function tipModal (updateManager) {
    Taro.showModal({
      title: '更新提示',
      content: '新版本已经准备好，是否马上重启小程序？',
      success: function (res) {
          if (res.confirm) {
              // 新的版本已经下载好，调用 applyUpdate 应用新版本并重启
              try {
                  // Taro.clearStorageSync()
              } catch(e) {
                // Do something when catch error
              }
              updateManager.applyUpdate()
          } else {
            if (isForce) {
              tipModal(updateManager)
            }
          }
      }
  })
  }
  if (process.env.TARO_ENV === 'weapp') {
      const updateManager = Taro.getUpdateManager()
      updateManager.onCheckForUpdate(function (res) {
          // 请求完新版本信息的回调
          console.log('是否有新版本: ', res.hasUpdate)
      })

      updateManager.onUpdateReady(function () {
          tipModal(updateManager)
      })

      updateManager.onUpdateFailed(function () {
        // 新的版本下载失败
        console.log('新的版本下载失败')
      })
  }
}

// 获取用户当前的授权状态
export async function checkAuthSetting(authSettingName) {
  return new Promise((resolve) => {
    Taro.getSetting({
      success(res) {
        // console.log('authSettingName-res', res)
        if (res.authSetting[authSettingName]) {
          resolve(true);
          console.log('授权过');
        } else {
          resolve(false);
          console.log('未授权过');
        }
      },
    });
  });
}
// 发起授权请求
export async function authSeting(authSettingName) {
  return new Promise((resolve) => {
    Taro.authorize({
      scope: authSettingName,
      success(res) {
        resolve(true);
        console.log(`${authSettingName}授权成功`, res);
      },
      fail() {
        resolve(false);
        console.log('授权失败');
      },
    });
  });
}
// 打开设置界面
export async function openSetting(authSettingName) {
  return new Promise((resolve) => {
    Taro.openSetting({
      success(res) {
        if (res.authSetting[authSettingName]) {
          resolve(true);
        } else {
          resolve(false);
        }
        console.log('授权设置', res);
      },
      fail() {
        resolve(false);
        console.log('设置失败');
      },
    });
  });
}
// 例子：userAPIAuthSeting('scope.userLocation',{},getLocation)
export async function userAPIAuthSeting(authSettingName, options, fn = ()=> {}) {
  const isAuthed = await checkAuthSetting(authSettingName);
  if (isAuthed) {
    // 授权过
    fn();
    return
  }

  const isAuthSuccess = await authSeting(authSettingName);
  if (isAuthSuccess) {
    // 授权成功
    fn();
    return
  }

  const defOptions = {
    content: '检测到您没打开相应授权，是否去设置打开？',
    confirmText: '确认',
    cancelText: '取消',
  };
  Taro.showModal({
      ...defOptions,
      ...options,
      success: async function (res) {
        if (res.confirm) {
          // 打开授权界面
          const result = await openSetting(authSettingName);
          if (result) {
            fn();
          }
        } else {
          console.log('用户点击取消');
        }
      },
    });
}

export const OSS_UGLIFY = (function() {
  const obj = {
    format_quality: '?x-oss-process=image/resize,p_100/quality,q_80/format,jpg',
    format_w: '?x-oss-process=image/resize,w_650/interlace,1/format,jpg',
    format_small_w: '?x-oss-process=image/resize,w_200/interlace,1/format,jpg',
  }

  const choose = (src, oss_select) => {
    return src ? src + obj[oss_select] : ''
  }
  return {
    format_quality: (src) => choose(src, 'format_quality'),
    format_w: (src) => choose(src, 'format_w'),
    format_small_w: (src) => choose(src, 'format_small_w'),
  }
})()

export const throttle = (fn) => {
  let timer = false
  function throttled(...args) {
    if (!timer) {
      timer = true
      fn.call(this, ...args)
    }
  }
  throttled.cancel = function (){
    timer = false
  }
  return throttled
}

export const getStoregeByKey = (key:string) => {
  try {
    var value = Taro.getStorageSync(key)
    return Promise.resolve(value)
  } catch (e) {
    // Do something when catch error
    Promise.reject(e)
  }
}

export const setStoregeByKey = (key:string, val:any) => {
  try {
    var value = Taro.getStorageSync(key)
    return Promise.resolve(value)
  } catch (e) {
    // Do something when catch error
    Promise.reject(e)
  }
}

export const showFloorSchoolList = []
// export const showFloorSchoolList = ['1407552954791690240']
